package zx.x.modules.app.utils;


import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.ObjectListing;
import com.aliyun.oss.model.ObjectMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;


public class xOSS {

    private final static Logger logger = LoggerFactory.getLogger(xOSS.class);

    private static String _bucket;

    private static String url;

    private static String head = "https://";
    private static String end ="/";

    // 至少在我这边 Client 线程内唯一，避免每次 new / shutdown 不够麻烦的
    private final static OSSClient _oc = _getOC();

    private final static OSSClient _getOC() {

        if (null != _oc) return _oc;

        // 由通用配置文件管理，smOSS 是个静态类不能 Autowired 也没有 @Value 只能手读
//            Properties p = PropertiesLoaderUtils.loadProperties(
//                    new ClassPathResource("application.yml")
//            );

        _bucket = "yunchenbucket";
        url = "yunchenbucket.oss-cn-qingdao.aliyuncs.com";

        return new OSSClient(
                "oss-cn-qingdao.aliyuncs.com", new DefaultCredentialProvider(
                "LTAI5tEFowcuBXS2VrEYf8Vb", "v35FimILVIIBhGtGaTuUClysRQ9aCZ"
        ), null
        );
//            _bucket = p.getProperty("oss.bucketName");
//            url = p.getProperty("oss.bucketUrl");
//
//            return new OSSClient(
//                    p.getProperty("oss.endPoint"), new DefaultCredentialProvider(
//                    p.getProperty("oss.accessKeyId"), p.getProperty("oss.accessKeySecret")
//            ), null
//            );

    }

    public final static path path(String path) {
        return new path(path);
    }

    public static class path {
        private String _path;

        private path(String path) {
            _path = path;
        }

        public String[] transfer(MultipartFile[] files) {
            String hash[] = new String[files.length];
            int i = 0;
            for (MultipartFile file : files)
                hash[i++] = transfer(file);
            return hash;
        }
        public String transfer(MultipartFile file) {
            //暂时限制5M 具体限制多大不知道 没人定没人说
            if (file.getSize() > 20971520) throw new xException("图片太大");
            try {

                // 存文件 MD5，避免同文件多存，这如果能撞上也是可以买彩票的概率了
                final String hash = _path + "/" + new BigInteger(
                        1, MessageDigest.getInstance("MD5").digest(file.getBytes())
                ).toString(16);
                // 只有不存在才过网，反正 OSS 不存在恶意文件，不判 contentType 避免用户抱怨传不上文件
                if (!_oc.doesObjectExist(_bucket, hash))
                    _oc.putObject(_bucket, hash, file.getInputStream(), new ObjectMetadata() {{
                        setContentType(file.getContentType());
                    }});
//                return head + url + end + hash;
                return hash;

            } catch (Exception ex) {
                logger.info(ex.getMessage());
                throw new xException("上传失败");
            }

        }

    }

    // for debug purpose 实际项目中没用到，万一将来有用就不删了
    public final static List<String> list() {

        // 列出文件，这玩意叫 List 但居然不是个 List 好烦
        ObjectListing listing = _oc.listObjects(_bucket);

        // 转 List
        List<String> list = new ArrayList<>();
        for (int i = 1; i < listing.getObjectSummaries().size(); i++)
            list.add(listing.getObjectSummaries().get(i).getKey());

        return list;

    }
}
